﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.ServiceModel.Security.Tokens;
using System.Security.Cryptography;
using System.Text;
using System.ServiceModel.Security;

namespace PSE.Framework.Common.Security.Services.Authentication.ClientCredentials
{
    internal class CustomClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager
    {
        CustomClientCredentials credentials;

        public CustomClientCredentialsSecurityTokenManager(CustomClientCredentials credentials)
            : base(credentials)
        {
            this.credentials = credentials;
        }

        private string CreateTokenId(string userName, string password, string host)
        {
            return CalculateMD5Hash(userName + password + host);
        }

        /// <summary>
        /// Calcular um HashMd5
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private string CalculateMD5Hash(string input)
        {
            Cryptography.HashCryptographer md5 = new Cryptography.HashCryptographer(Cryptography.HashCryptographer.Algorithm.MD5);
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // Segundo passo, converter o array de bytes em uma string haxadecimal
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));
            }
            return sb.ToString();
        }



        public override SecurityTokenProvider CreateSecurityTokenProvider(
            SecurityTokenRequirement tokenRequirement)
        {
            ////// Verifica se o Tipo do Token é um BvmfToken
            //if (tokenRequirement.TokenType == Constants.BvmfTokenType)
            //    return new TokenProvider(credentials.UserInfo);

            //Verifica se a requisição é para um IssuedToken
            if (IsIssuedSecurityTokenRequirement(tokenRequirement))
            {
                IssuedSecurityTokenProvider issuedSecurityTokenProvider = (IssuedSecurityTokenProvider)base.CreateSecurityTokenProvider(tokenRequirement);

                string tokenId = CreateTokenId(this.credentials.UserName.UserName, this.credentials.UserName.Password, issuedSecurityTokenProvider.TargetAddress.Uri.Host);

                return new CachedIssuedSecurityTokenProvider(issuedSecurityTokenProvider, tokenId);
            }

            else if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
            {
                if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
                {
                    return new X509SecurityTokenProvider(credentials.ServiceCertificate.DefaultCertificate);
                }
            }

            return base.CreateSecurityTokenProvider(tokenRequirement);
        }

        /// <summary>
        /// Cria uma instância de um <see cref="BvmfTokenSerializer"/>.
        /// </summary>
        /// <param name="version"></param>
        /// <returns></returns>
        public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
        {
            //TODO: Precisa passar o version?
            return new WSSecurityTokenSerializer(); //BvmfTokenSerializer(version);
        }
    }

}
